package com.zhao.dota.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhao.dota.common.contant.CommonConst;
import com.zhao.dota.contant.CacheConstant;
import com.zhao.dota.mapper.HeroMapper;
import com.zhao.dota.model.Hero;
import com.zhao.dota.service.HeroService;
import com.zhao.dota.util.SteamUtil;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

@Service
@CacheConfig(cacheNames = CacheConstant.HERO)
public class HeroServiceImpl extends ServiceImpl<HeroMapper, Hero> implements HeroService {

    @Resource
    private RedisTemplate<String, Hero> redisTemplate;

    @Override
    @Caching(evict = {@CacheEvict(key = "'id:'.concat(#heroList.id)"), @CacheEvict(key = "'name:'.concat(#heroList.name)")})
    public int updateList(List<Hero> heroList) {
        int count = 0;
        List<String> keys = new ArrayList<>();
        for (Hero hero : heroList) {
            Hero old = getByName(hero.getName());
            if (old == null) {
                count += save(hero) ? 1 : 0;
            } else {
                keys.add(CacheConstant.HERO + ":name:" + old.getName());
                BeanUtil.copyProperties(hero, old, CommonConst.IGNORE_NULL_VALUE);
                count += updateById(old) ? 1 : 0;
            }
            keys.add(CacheConstant.HERO + ":id:" + hero.getId());
        }
        try {
            redisTemplate.delete(keys);
        } catch (Exception ignored) {}
        return count;
    }


    @Override
    @Cacheable(key = "'name:'.concat(#name)", unless = "#result == null")
    public Hero getByName(String name) {
        LambdaQueryWrapper<Hero> query = Wrappers.lambdaQuery(Hero.class).eq(Hero::getName, name);
        Hero hero = getOne(query);
        if (hero != null) {
            hero.setAvatar(SteamUtil.getIconUrlByHeroName(hero.getName()));
            hero.setAvatarFull(SteamUtil.getIconUrlByHeroName(hero.getName()));
        }
        return hero;
    }

    @Override
    @Cacheable(key = "'id:'.concat(#id)", unless = "#result == null")
    public Hero getById(Serializable id) {
        Hero hero = super.getById(id);
        if (hero == null) {
            return null;
        }
        hero.setAvatar(SteamUtil.getIconUrlByHeroName(hero.getName()));
        hero.setAvatarFull(SteamUtil.getIconUrlByHeroName(hero.getName()));
        return hero;
    }

    @Override
    @Caching(evict = {@CacheEvict(key = "'id:'.concat(#entity.id)"), @CacheEvict(key = "'name:'.concat(#entity.name)")})
    public boolean save(Hero entity) {
        return super.save(entity);
    }

    @Override
    @Caching(evict = {@CacheEvict(key = "'id:'.concat(#entity.id)"), @CacheEvict(key = "'name:'.concat(#entity.name)")})
    public boolean updateById(Hero entity) {
        return super.updateById(entity);
    }
}
